package com.mjawor.lpgroovy

/**
 * Author: Mateusz Jaworski
 */
class SumImpl implements Cloneable {

	private TreeMap<String, xVarImpl> variablesMap = new TreeMap<String, xVarImpl>()

    SumImpl() {}

    SumImpl(xVarImpl... vars) {
        add(vars)
	}

	SumImpl add(xVar... vars) {
        vars.collect { var ->
            String id = var.getVariable().id
            if(variablesMap.containsKey(id)) {
                variablesMap.put(id,variablesMap.get(id) + var)
            } else {
                variablesMap.put(id,var)
            }
        }
		return this
	}

	SumImpl plus(SumImpl s) {
		SumImpl sum = new SumImpl()
		sum.add(variablesMap.values().toArray(new xVarImpl[variablesMap.size()]))
        sum.add(s.variablesMap.values().toArray(new xVarImpl[s.variablesMap.size()]))
		return sum
	}

	SumImpl negative() {
        SumImpl result = new SumImpl();
		variablesMap.values().each { result.add(-it.clone()) }
		return result
	}

	Collection<xVarImpl> getVariables() {
		return variablesMap.values()
	}

    @Override
	String toString() {
		return variablesMap.values().collect { it }.join(' + ') as String
	}

    @Override
    boolean equals(s2) {
        if (this.is(s2)) return true;
        if (!(s2 instanceof SumImpl)) return false;

        if(s2.variablesMap.size() != variablesMap.size()) {
            return false
        }
        variablesMap.keySet().collect { id ->
            if(!s2.variablesMap.containsKey(id)) {
                return false
            } else if(s2.variablesMap.get(id).coefficient != variablesMap.get(id).coefficient) {
                return false
            }
        }
        return true
    }

    @Override
    Object clone() {
        SumImpl result = new SumImpl();
		variablesMap.values().each { result.add(it.clone()) }
		return result
    }

}
